package com.kurancy.web.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kurancy.authentication.config.FacebookConfig;
import com.kurancy.web.authentication.RegistrationNotFoundException;
import com.kurancy.web.authentication.SessionManager;
import com.kurancy.web.authentication.service.AuthService;
import com.kurancy.web.controller.form.KurancyCreatedSearchForm;
import com.kurancy.web.controller.form.RegisterAuthenticationForm;

@Controller
public class AuthenticationController {
	
	@Autowired
	private AuthService authService;
	
	@Autowired
	private SessionManager sessionManager;

	@RequestMapping("/authenticate")
    public String authenticate() {
		
    		return "authentication/index";
    }
	
	@Autowired
	private FacebookConfig facebookConfig;
	
	@RequestMapping("/requestFBAuth")
	public void requestFBAuth(HttpServletResponse resp) throws IOException {
		resp.sendRedirect(facebookConfig.getLoginRedirectURL());
	}
	
	@RequestMapping("/register-authentication")
	public @ResponseBody KurancyCreatedSearchForm registerAuthentication(@ModelAttribute("authContainer") RegisterAuthenticationForm form, 
										BindingResult bindingResult, 
										ModelMap map, 
										Model uiModel, 
										HttpServletRequest httpServletRequest) {
		return new KurancyCreatedSearchForm();
	}
	
	@RequestMapping("/fbauth")
	public String fbAuth(HttpServletRequest request, HttpServletResponse response, ModelMap map) throws MalformedURLException {
		String code = request.getParameter("code");
        if (code != null && code.length() > 0) {
            String authURL = facebookConfig.getAuthURL(code);
            URL url = new URL(authURL);
            try {
                String result = readURL(url);
                String accessToken = null;
                Integer expires = null;
                String[] pairs = result.split("&");
                for (String pair : pairs) {
                    String[] kv = pair.split("=");
                    if (kv.length != 2) {
                        throw new RuntimeException("Unexpected auth response");
                    } else {
                        if (kv[0].equals("access_token")) {
                            accessToken = kv[1];
                        }
                        if (kv[0].equals("expires")) {
                            expires = Integer.valueOf(kv[1]);
                        }
                    }
                }
                if (accessToken != null && expires != null) {
                	try {
                		//authService.authFacebookLogin(accessToken, expires, request);
                		authService.retrieveUser(accessToken, null);
                		
                	} catch (RegistrationNotFoundException nfe) {
                		sessionManager.setKurancyUser(request, nfe.getUnregisteredKurancyUser());
                		response.sendRedirect("/prepareregistration");
                	}
                    
                } else {
                    throw new RuntimeException("Access token and expires not found");
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "myKurancy/index";
	}
	
	private String readURL(URL url) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream is = url.openStream();
        int r;
        while ((r = is.read()) != -1) {
            baos.write(r);
        }
        return new String(baos.toByteArray());
    }
}
